package com.tcs.tsrm;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.GregorianCalendar;

import com.tcs.tsrm.beans.ClusteringThresholds;
import com.tcs.utils.GetNontrivialSubs;
import com.tcs.utils.PrepareForRanking;
import com.tcs.utils.Ranking;
import com.tcs.utils.RepeatableClusters;

public class CoinFreqMotifDiscovery {
	/**
	 * To run complete Motif discovery process which includes : Clustering,
	 * Removal of Repeated Clusters, Removal of Trivial Matches and Ranking
	 * 
	 * @param args
	 * @throws URISyntaxException
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException,
			URISyntaxException {
		GregorianCalendar date = new GregorianCalendar();

		CoinFreqMotifDiscovery rmd = new CoinFreqMotifDiscovery();
		ClusteringThresholds thresholds = null;
		if (args.length < 1) {
			System.err.println("Not enough Arguments given.");
			System.err.println("provide property filename as argument");
			System.err
					.println("For example: java com.tcs.tsrm.CoinFreqMotifDiscovery sample");
			return;
		} else if (args.length == 1) {
			thresholds = new ClusteringThresholds(args[0], "Complete");
		} else if (args.length > 1) {
			System.err.println("Too Many Arguments Given");
			System.err
					.println("provide only the property filename as argument");
			System.err
					.println("For example: java com.tcs.tsrm.CoinFreqMotifDiscovery sample");
			return;
		}
		rmd.setDefaultThresholds(thresholds);
		RangeMotifDiscovery runner = new RangeMotifDiscovery();
		runner.execute(thresholds);

		System.out.println("Clustering Done...");
		GregorianCalendar date2 = null;

		rmd.postClusteringProcess(thresholds);
		date2 = new GregorianCalendar();
		System.out
				.println("Total time taken including I/O is ->"
						+ ((double) (date2.getTimeInMillis() - date
								.getTimeInMillis()) / 1000) + " seconds");

		System.out.println("FINISHED");

	}

	/**
	 * @param thresholds
	 */
	private void setDefaultThresholds(ClusteringThresholds thresholds) {
		String currentDirectory = new File("").getAbsolutePath();
		thresholds.setPrintClusters(true);
		thresholds.setPrintNonTrivialMatrix(true);
		thresholds.setPrintOriginalMatrix(true);
		thresholds.setDataInputPath(currentDirectory + "/input-data/");
	}

	/**
	 * @param thresholds
	 */
	private void postClusteringProcess(ClusteringThresholds thresholds) {
		findNonRepeatingClusters(thresholds);
		removeTrivialMatches(thresholds);
		findNonRepeatingClusters2(thresholds);
		prepareForRanking(thresholds);
		rankTheMotifs(thresholds);
	}

	private void prepareForRanking(ClusteringThresholds thresholds) {
		String currentDirectory = new File("").getAbsolutePath();
		PrepareForRanking.clusterIndexesPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/2-Non-Repeatable-Clusters.txt")
				.getAbsolutePath();
		PrepareForRanking.originalMatrixPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "OriginalMatrix.txt")
				.getAbsolutePath();
		PrepareForRanking.outputPath = new File(currentDirectory + "/Output"
				+ "/" + thresholds.getAlgorithm() + "/"
				+ thresholds.getSensorName() + thresholds.getMotifWidth() + "/")
				.getAbsolutePath();
		PrepareForRanking.nonTrivialMatrixPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "NonTrivialMatrix.txt")
				.getAbsolutePath();
		PrepareForRanking runner = new PrepareForRanking();
		runner.computeNonTrivialSubs(thresholds);
	}

	/**
	 * @param thresholds
	 */
	private void rankTheMotifs(ClusteringThresholds thresholds) {
		String currentDirectory = new File("").getAbsolutePath();
		String inputFolderPath = new File(currentDirectory + "/Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "NonTrivial/Motifs-Org-2/")
				.getAbsolutePath();	
		String outputFolderPath = new File(currentDirectory + "/Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "FinalMotifs")
				.getAbsolutePath();

		Ranking rank = new Ranking();
		try {
			rank.getRankedMotifs(inputFolderPath, outputFolderPath, thresholds);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("Ranking Done...");

	}

	/**
	 * @param thresholds
	 *            -
	 */
	private void removeTrivialMatches(ClusteringThresholds thresholds) {
		String currentDirectory = new File("").getAbsolutePath();
		GetNontrivialSubs.clusterIndexesPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "-Non-Repeatable-Clusters.txt")
				.getAbsolutePath();
		GetNontrivialSubs.originalMatrixPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "OriginalMatrix.txt")
				.getAbsolutePath();
		GetNontrivialSubs.outputPath = new File(currentDirectory + "/Output"
				+ "/" + thresholds.getAlgorithm() + "/"
				+ thresholds.getSensorName() + thresholds.getMotifWidth() + "/")
				.getAbsolutePath();
		GetNontrivialSubs.nonTrivialMatrixPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "NonTrivialMatrix.txt")
				.getAbsolutePath();
		GetNontrivialSubs runner = new GetNontrivialSubs();
		runner.computeNonTrivialSubs(thresholds);
		System.out.println("Trivial Match Removal Done...");
	}

	/**
	 * @param thresholds
	 */
	private void findNonRepeatingClusters(ClusteringThresholds thresholds) {
		RepeatableClusters rc = new RepeatableClusters();
		String clusterIndexesPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "Clusters-Indexes.txt")
				.getAbsolutePath();
		String currentDirectory = new File("").getAbsolutePath();
		String nonRepeatingClustersOutputPath = new File(currentDirectory
				+ "/Output" + "/" + thresholds.getAlgorithm() + "/"
				+ thresholds.getSensorName() + thresholds.getMotifWidth() + "/")
				.getAbsolutePath();
		try {
			rc.findNonRepeatingClusters(clusterIndexesPath,
					nonRepeatingClustersOutputPath, thresholds);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private void findNonRepeatingClusters2(ClusteringThresholds thresholds) {
		RepeatableClusters rc = new RepeatableClusters();
		String clusterIndexesPath = new File("Output" + "/"
				+ thresholds.getAlgorithm() + "/" + thresholds.getSensorName()
				+ thresholds.getMotifWidth() + "/" + "NonTrivial" + "/"
				+ "Clusters-Indexes.txt").getAbsolutePath();
		String currentDirectory = new File("").getAbsolutePath();
		String nonRepeatingClustersOutputPath = new File(currentDirectory
				+ "/Output" + "/" + thresholds.getAlgorithm() + "/"
				+ thresholds.getSensorName() + thresholds.getMotifWidth()
				+ "/2/").getAbsolutePath();
		try {
			rc.findNonRepeatingClusters(clusterIndexesPath,
					nonRepeatingClustersOutputPath, thresholds);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
